home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
others
/
ole_101.zip
/
PATRON.ZIP
/
OLECLI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-13
|
8KB
|
317 lines
/*
* OLECLI.C
*
* Constructor, Destructor, and the single method "CallBack" (called
* ClientCallback here) for the CLIENT structure. The OLECLI DLL calls
* ClientCallback through the OLECLIENTVTBL stored with this structure.
*
* The CLIENT structure contains a pointer to the application-wide
* OLESTREAM structure.
*
* Copyright(c) Microsoft Corp. 1992 All Rights Reserved
*/
#include <windows.h>
#include <ole.h>
#include "oclient.h"
//Array of string pointers, global to OLE-specific code.
char NEAR *rgpszOLE[COLESTRINGS];
/*
* PClientAllocate
*
* Purpose:
* Constructor method for the CLIENT data type. Allocates a CLIENT
* and sets the defaults in its fields:
* Initalize OLECLIENTVTBL and OLESTREAMVTBL
* Allocate and initialize an OLESTREAM structure (see OLESTREA.C)
* Register OLE clipboard formats
* Allocate scratch data and set pointers within it.
*
* Used from application initialization.
*
* Parameters:
* pfSuccess LPBOOL indicating if the initialization succeeded. If
* this function returns non-NULL, but *pfSuccess==FALSE,
* the caller must call the destructor function.
* hInst HANDLE of the application instance.
* pfnCallBack FARPROC to the single client method to initialize.
* We pass this function to PVtblClientAllocate.
*
* Return Value:
* LPCLIENT Pointer to the allocated CLIENT if successful, NULL
* if the allocation failed or a parameter is invalid.
*/
LPCLIENT FAR PASCAL PClientAllocate(LPBOOL pfSuccess, HANDLE hInst,
LPCLIENTCALLBACK pfnCallBack)
{
LPCLIENT pCli;
HANDLE hMem;
BOOL fTemp;
/*
* Any error condition will return FALSE unless we get all through
* this function. This scheme allows us to always return on any
* error instead of trying to clean up what was already initialized.
* Instead, we let the destructor, PClientFree, do the work.
*/
if (NULL==pfSuccess)
return NULL;
*pfSuccess=FALSE;
if (NULL==hInst)
return NULL;
//Allocate this structure.
hMem=LocalAlloc(LPTR, CBCLIENT);
if (NULL==hMem)
return NULL;
pCli=(LPCLIENT)(PSTR)hMem;
//Go load the strings for OLE before we start using them
pCli->hMemStrings=HLoadOLEStrings(hInst);
if (NULL==pCli->hMemStrings)
return pCli;
//1. Register clipboard formats; the strings are globals in this file.
pCli->cfNative =RegisterClipboardFormat(PSZOLE(IDS_NATIVE));
pCli->cfOwnerLink =RegisterClipboardFormat(PSZOLE(IDS_OWNERLINK));
pCli->cfObjectLink=RegisterClipboardFormat(PSZOLE(IDS_OBJECTLINK));
//Any error, return what we already allocated.
if (0==pCli->cfNative || 0==pCli->cfOwnerLink || 0==pCli->cfObjectLink)
return pCli;
//2. Get initialized OLECLIENTVTBL pointer.
pCli->pvt=PVtblClientAllocate(&fTemp, hInst, pfnCallBack);
if (!fTemp)
return pCli;
//3. Get an initialized STREAM pointer.
pCli->pStream=PStreamAllocate(&fTemp, hInst);
if (!fTemp)
return pCli;
//4. Allocate scratch memory.
pCli->hData=GlobalAlloc(GHND, CSCRATCH*CBSCRATCH);
if (NULL==pCli->hData)
return pCli;
/*
* Initialize global pointers into this memory. Since we know we
* allocated with a nonzero byte count, GlobalLock will work.
*/
pCli->pszData1=GlobalLock(pCli->hData);
pCli->pszData2=pCli->pszData1+CBSCRATCH;
pCli->pszData3=pCli->pszData2+CBSCRATCH;
//Everything handled successfully.
*pfSuccess=TRUE;
return pCli;
}
/*
* PClientFree
*
* Purpose:
* Frees all data in the CLIENT and frees the structure.
*
* Parameters:
* pCli LPCLIENT to the structure to free.
*
* Return Value:
* LPCLIENT NULL if the function succeeds, pCli otherwise.
*/
LPCLIENT FAR PASCAL PClientFree(LPCLIENT pCli)
{
BOOL fRet=FALSE;
/*
* Free the scratch memory if we have any. No need to clear the
* pointers since we'll be freeing this structure anyway.
*/
if (NULL!=pCli->hData)
GlobalFree(pCli->hData);
//Free the stream we're holding
if (NULL!=PStreamFree(pCli->pStream))
return pCli;
//Free this object's VTBL
if (NULL!=PVtblClientFree(pCli->pvt))
return pCli;
//Free the strings
if (NULL!=pCli->hMemStrings)
LocalFree(pCli->hMemStrings);
if (NULL!=LocalFree((HANDLE)(DWORD)pCli))
return pCli;
return NULL;
}
/*
* PClientWindowSet
*
* Purpose:
* Informs the CLIENT structure about the main application window
* which it needs to post messages from ClientCallback.
*
* Parameters:
* pCli LPCLIENT to the structure concerned.
* hWnd HWND of the application window.
*
* Return Value:
* None
*/
void FAR PASCAL PClientWindowSet(LPCLIENT pCli, HWND hWnd)
{
if (NULL!=pCli)
pCli->hWnd=hWnd;
return;
}
/*
* PClientMsgProcSet
*
* Purpose:
* Informs the CLIENT structure about a function in the main application
* that translates and dispatches messages. This prevents the CLIENT
* from having to carry an accelerator handle or window handle and
* allows the application to perform other actions we cannot predict
* (like IsDialogMessage).
*
* Parameters:
* pCli LPCLIENT to the structure concerned.
* pfn LPFNMSGPROC to the message processing function.
*
* Return Value:
* None
*/
void FAR PASCAL PClientMsgProcSet(LPCLIENT pCli, LPFNMSGPROC pfn)
{
if (NULL!=pCli)
pCli->pfnMsgProc=pfn;
return;
}
/*
* HLoadOLEStrings
*
* Purpose:
* Allocates FIXED local memory and reads the applications
* string resources into that memory. Each string's pointer
* is available through the PSZOLE(i) macro where i is the ID
* value of the string. The strings must have sequential IDs.
*
* Note that string pointers are stored in the rgpszOLE global
* array defined in this file.
*
* Parameters:
* hInst HANDLE of the application instance.
*
* Return Value:
* HANDLE Handle to the local memory. NULL if memory could
* not be allocated.
*/
HANDLE PASCAL HLoadOLEStrings(HANDLE hInst)
{
HANDLE hMem;
char NEAR *pch;
WORD cchUsed=0;
WORD cch;
short i;
/*
* Allocate memory and load strings. NOTE! The LPTR style
* specifies FIXED memory. This should not be a big deal
* since this is an early allocation into the local heap.
* But it should be watched if the number of strings becomes
* large.
*/
hMem=LocalAlloc(LPTR, COLESTRINGS*CCHOLESTRINGMAX);
if (hMem==NULL)
return (HANDLE)NULL;
/*
* This operation is only valid for FIXED memory. Otherwise use
* LocalLock.
*/
pch=(char *)hMem;
/*
* Load the strings into the memory and retain the specific
* pointer to that string.
*/
for (i=0; i < COLESTRINGS; i++)
{
cch=LoadString(hInst, i, (LPSTR)(pch+cchUsed), CCHOLESTRINGMAX-1);
PSZOLE(i)=(char *)(pch+cchUsed);
/*
* One is added to cch to include a NULL. The memory was ZEROINITed
* on allocation so by skipping a byte we get the NULL.
*/
cchUsed +=cch+1;
}
/*
* We are assuming that no string is over CCHSTRINGMAX, and therefore
* we did not use all the allocated memory. Therefore LocalReAlloc
* will only SHRINK the block, never expand it. So if it fails, we
* don't care--all the strings are still there, we just wasted some
* space.
*/
LocalReAlloc(hMem, cchUsed+1, LPTR);
return hMem;
}